using System;
using System.Collections.Generic;

namespace RobotsFight.RobotImplementation
{

    public enum Direction
    {
        Top, Left, Bottom, Right
    }

    public abstract class CoordinateStorage
    {
        public abstract void AddCordinate(int x, int y);
        public abstract bool HasBeenAtCoordinate(int x, int y);
        public abstract bool IsRobotBlocked(int x, int y,bool isRigtMost,bool isBottomMost);

        public abstract void FreeRobot(int x, int y, Direction d);
    }

    public class ListCoordinateStorage : CoordinateStorage
    {
        private class CoordiantesPair
        {
            public int X { get; set; }
            public int Y { get; set; }
        }

        private List<CoordiantesPair> _coordinates = new List<CoordiantesPair>();


        public override void AddCordinate(int x, int y)
        {
           _coordinates.Add(new CoordiantesPair(){X = x,Y=y});
        }

        public override bool HasBeenAtCoordinate(int x, int y)
        {
            foreach (CoordiantesPair p in _coordinates)
            {
                if (p.X == x && p.Y == y)
                    return true;
            }

            return false;
        }

        public override bool IsRobotBlocked(int x, int y, bool isRigtMost, bool isBottomMost)
        {
            throw new NotImplementedException();
        }



        public override void FreeRobot(int x, int y, Direction d)
        {
            throw new NotImplementedException();
        }
    }

    public class MatrixCoordinateStorage : CoordinateStorage
    {
        private bool[,] _storage;

        public MatrixCoordinateStorage(int maxX,int maxY)
        {
            _storage = new bool[maxX, maxY];
        }


        public override void AddCordinate(int x, int y)
        {
            _storage[x, y] = true;
        }

        public override bool HasBeenAtCoordinate(int x, int y)
        {
            return _storage[x, y];
        }

        public override bool IsRobotBlocked(int x, int y, bool isRigtMost, bool isBottomMost)
        {
            throw new NotImplementedException();
        }



        public override void FreeRobot(int x, int y, Direction d)
        {
            throw new NotImplementedException();
        }
    }

    public class DictionaryCoordinateStorage: CoordinateStorage
    {
        HashSet<DicKey> _set = new HashSet<DicKey>();

        private class DicKey
        {
            public int X { get;  set; }
            public int Y { get;  set; }

            public override int GetHashCode()
            {
                return this.X ^ (this.Y << 16);
            }

            public override bool Equals(object obj)
            {
                DicKey k2 = obj as DicKey;
                if (k2 != null)
                {
                    return this.X == k2.X && this.Y == k2.Y;
                }
                return false;
            }
        }

        public override void AddCordinate(int x, int y)
        {
            _set.Add(new DicKey() { X = x, Y = y });
        }

        public override bool HasBeenAtCoordinate(int x, int y)
        {
            return _set.Contains(new DicKey() { X = x, Y = y });
        }

        public override bool IsRobotBlocked(int x, int y, bool isRigtMost, bool isBottomMost)
        {
            bool isLeftFree;

            if (x == 0)
                isLeftFree = false;
            else
                isLeftFree = !HasBeenAtCoordinate(x - 1, y);

            bool isTopFree;

            if (y == 0)
                isTopFree = false;
            else
                isTopFree = !HasBeenAtCoordinate(x, y - 1);

            bool isBottomFree;

            if (isBottomMost)
                isBottomFree = false;
            else
                isBottomFree = !HasBeenAtCoordinate(x, y + 1);
            
            
            bool isRightFree;

            if (isRigtMost)
                isRightFree = false;
            else
                isRightFree = !HasBeenAtCoordinate(x + 1, y);

            return !(isLeftFree && isTopFree && isBottomFree && isRightFree);
        }

       

        public override void FreeRobot(int x,int y, Direction d)
        {
            switch (d)
            {
                case Direction.Top:
                    _set.RemoveWhere(di => di.X == x && di.Y == y - 1);
                    break;
                case Direction.Left:
                     _set.RemoveWhere(di => di.X == x - 1 && di.Y == y);
                    break;
                case Direction.Bottom:
                     _set.RemoveWhere(di => di.X == x && di.Y == y+ 1);
                    break;
                case Direction.Right:
                    _set.RemoveWhere(di => di.X == x + 1 && di.Y == y);
                    break;
                default:
                    break;
            }
        }
            

       
    }
}